/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cassandra.thrift.*;
import org.apache.thrift.TException;
import pojo.Status;
import common.GeneralHandling;
import java.util.*;
import org.apache.commons.codec.binary.StringUtils;
import pojo.Counter;
import pojo.Page;
import pojo.Tag;
import org.apache.commons.lang.StringEscapeUtils;
import Search.solrSearch;

/**
 *
 * @author huy
 */
public class StatusDAO {
    private static Cassandra.Client client;
    private static StatusDAO instance;
    
    public static StatusDAO getInstance(Cassandra.Client _client)
    {
        if (instance != null)
            return instance;
        instance = new StatusDAO();
        client = _client;
        return instance;
    }  

    
    public boolean insertStatus(String content,String list_tags)
    {
        boolean result = false;
        try {
            Status newstatus = new Status();
            newstatus.setContent(content);
            newstatus.setTags(list_tags);
            newstatus.setLike_count("0");
            newstatus.setDislike_count("0");
            ColumnParent parent = new ColumnParent(Status.col_parent);
            ByteBuffer status_ID = common.GeneralHandling.toByteBuffer(UUID.randomUUID().toString());
            
            //Add các column vào CF.
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_content, newstatus.getContent()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_tags, newstatus.getTags()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_likecount, newstatus.getLike_count()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_dislikecount, newstatus.getDislike_count()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_createdate, ""),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_modifydate, ""),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_state, "public"),common.Constants.CL);
            
            //Cập nhật list_status_ID cho tag tương ứng.
            String[] tags = newstatus.getTags().split(",");
            TagDAO tag_DAO = TagDAO.getInstance(client);
            String x = GeneralHandling.toString(status_ID);
            for (int i = 0; i < tags.length; i++) {
                if (!tag_DAO.InsertStatusIDToTag(x, tags[i]))
                    return result;
            }
            CounterDAO.Inscrease(Counter.key_status, client);;
            result = true;
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    public boolean updateContentStatus(String statusID, String content)
    {
        boolean result = false;
        try {
            Status newstatus = new Status();
            newstatus.setContent(content);
            ColumnParent parent = new ColumnParent(Status.col_parent);
            ByteBuffer status_ID = common.GeneralHandling.toByteBuffer(statusID);
            
            //Add các column vào CF.
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_content, newstatus.getContent()),common.Constants.CL);

            result = true;
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    public String selectStatusFromID(String statusID){
        String result = "";
        try {
                ByteBuffer id = common.GeneralHandling.toByteBuffer(statusID);
                ColumnParent parent = new ColumnParent(Status.col_parent);
            
                SlicePredicate predicate = new SlicePredicate();
                predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
                predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
                predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_state));
                List<ColumnOrSuperColumn> p_listkey = client.get_slice(id, parent, predicate, common.Constants.CL);
               
                List<KeySlice> listStatusId = new ArrayList<KeySlice>();
                    KeySlice kSlide = new KeySlice();
                    kSlide.key =id;
                    for(int i = 0; i < p_listkey.size(); i++){
                        
                        ColumnOrSuperColumn colOrSuspCol = p_listkey.get(i);
                        kSlide.addToColumns(colOrSuspCol);
                    }
                    listStatusId.add(kSlide);
                    result = ParseToJSON(listStatusId);

        }  catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;    
    }

    public boolean insertStatus(String content,String list_tags, String state)
    {
        boolean result = false;
        try {
            Status newstatus = new Status();
            newstatus.setContent(content);
            newstatus.setTags(list_tags);
            newstatus.setLike_count("0");
            newstatus.setDislike_count("0");
            ColumnParent parent = new ColumnParent(Status.col_parent);
            ByteBuffer status_ID = common.GeneralHandling.toByteBuffer(UUID.randomUUID().toString());
            
            //Add các column vào CF.
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_content, newstatus.getContent()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_tags, newstatus.getTags()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_likecount, newstatus.getLike_count()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_dislikecount, newstatus.getDislike_count()),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_createdate, ""),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_modifydate, ""),common.Constants.CL);
            client.insert(status_ID,parent,GeneralHandling.createCol(Status.colname_state, state),common.Constants.CL);
            
            //Cập nhật list_status_ID cho tag tương ứng.
            String[] tags = newstatus.getTags().split(",");
            TagDAO tag_DAO = TagDAO.getInstance(client);
            String x = GeneralHandling.toString(status_ID);
            for (int i = 0; i < tags.length; i++) {
                if (!tag_DAO.InsertStatusIDToTag(x, tags[i]))
                    return result;
            }
            CounterDAO.Inscrease(Counter.key_status, client);
            result = true;
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }    
    
    public boolean DeleteStatus(List<String> liststatusID)
    {
        boolean result = false;
        try {
            for (String deleteID : liststatusID)
            {
                ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(deleteID);
                ColumnPath path = new ColumnPath(Status.col_parent);
                ColumnParent parent = new ColumnParent(Status.col_parent);
                SlicePredicate predicate = new SlicePredicate();
                predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
                long timestamp = System.currentTimeMillis();
               
                List<ColumnOrSuperColumn> col = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
                String listtag = common.GeneralHandling.toString(col.get(0).column.value);
                String[] tags = listtag.split(",");
                client.remove(rowkey,path, timestamp, ConsistencyLevel.ONE);
                
                TagDAO tag_DAO = TagDAO.getInstance(client);
                for (int i = 0; i < tags.length; i++) {
                    result = tag_DAO.DeleteStatusIDInTag(tags[i], deleteID);
                }
                CounterDAO.Decrease(Counter.key_status, client);
            }
            return result;
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public boolean updateStateStatus(List<String> liststatusID, String newState)
    {
        boolean result = false;
        try {
            for(String rowkey : liststatusID){
                ByteBuffer id = common.GeneralHandling.toByteBuffer(rowkey);
                ColumnParent parent = new ColumnParent(Status.col_parent);

                ColumnPath path = new ColumnPath(Status.col_parent);
                path.column = common.GeneralHandling.toByteBuffer(Status.colname_state);

                Column newcol = common.GeneralHandling.createCol(Status.colname_state, newState);

                client.insert(id, parent, newcol, common.Constants.CL);
            }
            result = true;
        }  catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public String SelectRandom()
    {
        String result = "";
        try {
            
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            int soLuongStatus = CounterDAO.getCounterStatus(client);
            range.count = soLuongStatus;
            List<KeySlice> p_listkey = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            int keystart = (new Random()).nextInt(soLuongStatus);
            int count = (new Random()).nextInt(5) + 6;
            List<KeySlice> listkey = p_listkey.subList(keystart, keystart + count);
            result = ParseToJSON(listkey);
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    public String SelectNoTag()
    {
        String result = "";
        try{
            ByteBuffer cql = common.GeneralHandling.toByteBuffer("SELECT * FROM Status WHERE 74616773 = ''");
            CqlResult results = client.execute_cql_query(cql, Compression.NONE);
            List<KeySlice> listStatusId = new ArrayList<KeySlice>();
            for(CqlRow cRow: results.rows){
                KeySlice kSlide = new KeySlice();
                kSlide.key = cRow.key;
                for(Column col: cRow.columns){
                    ColumnOrSuperColumn colOrSupCol = new ColumnOrSuperColumn();
                    colOrSupCol.column = col;
                    kSlide.addToColumns(colOrSupCol);
                }
                listStatusId.add(kSlide);
            }
            result = ParseToJSON(listStatusId);
        } catch (SchemaDisagreementException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }    
    
    public String SelectRandomFromTag(String Tagname)
    {
        String result = "";
        try {
            
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Tagname);
            ColumnParent parent = new ColumnParent(Tag.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Tag.name_scol_lstatus));
            List<ColumnOrSuperColumn> result_key = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
            List<ByteBuffer> listStatusID = new ArrayList<ByteBuffer>();
            for (ColumnOrSuperColumn col : result_key) {
                for (Column c : col.getSuper_column().columns)
                    listStatusID.add(c.name);
            }
            //Xáo trôn list statusID
            Random rd = new Random();
            List<ByteBuffer> rdlist = new ArrayList<ByteBuffer>();
            int listSize = listStatusID.size() > 8 ? 8 : listStatusID.size();
            for (int i = 0; i < listSize; i++) {
                int pos = rd.nextInt(listStatusID.size());
                rdlist.add(listStatusID.get(pos));
                listStatusID.remove(pos);
            }
            result = Getliststatus(rdlist); 
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    public String SelectStatusFromTag(String Tagname)
    {
        String result = "";
        try {
            
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Tagname);
            ColumnParent parent = new ColumnParent(Tag.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Tag.name_scol_lstatus));
            List<ColumnOrSuperColumn> result_key = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
            List<ByteBuffer> listStatusID = new ArrayList<ByteBuffer>();
            for (ColumnOrSuperColumn col : result_key) {
                for (Column c : col.getSuper_column().columns)
                    listStatusID.add(c.name);
            }
            result = Getliststatus(listStatusID); 
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }    
    
    public boolean removeTagInStatus(String status_ID, String Tagname){
        boolean result = false;
         try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(status_ID);
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            ColumnPath path = new ColumnPath(Status.col_parent);
            path.column = common.GeneralHandling.toByteBuffer(Status.colname_tags);
            ColumnOrSuperColumn status = client.get(rowkey, path, common.Constants.CL);
            
            
            String oldTags = common.GeneralHandling.toString(status.column.value);
            
            //Begin: Xu ly chuoi tag
            String temp = Tagname + ",";
            String newTags = oldTags.replaceAll(temp, "");
            newTags = newTags.replaceAll(Tagname, "");
            if(newTags.length() != 0){
                if(newTags.charAt(newTags.length() -1) == ','){
                    newTags = newTags.substring(0, newTags.length() -1);
                }
            }
            //End: Xy ly chuoi tag
            Column newcol = common.GeneralHandling.createCol(Status.colname_tags, newTags);
            
            client.insert(rowkey, parent, newcol, common.Constants.CL);
            result = true;
        } catch (NotFoundException ex) {
            return false;
        }       catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return result;
    }
    public List<String> SelectAllStatusTag(String Tagname)
    {
        List<String>  listStatusID = new ArrayList<String>();
        try {
            
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Tagname);
            ColumnParent parent = new ColumnParent(Tag.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Tag.name_scol_lstatus));
                    
            List<ColumnOrSuperColumn> result_key = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
            
            for (ColumnOrSuperColumn col : result_key) {
                for (Column c : col.getSuper_column().columns)
                    listStatusID.add(common.GeneralHandling.toString(c.name));
            } 
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return listStatusID;
    }    
    
    
    public String Getliststatus(List<ByteBuffer> listStatusID)
    {
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
                
            Map<ByteBuffer, List<ColumnOrSuperColumn>> mapstatus = client.multiget_slice(listStatusID, parent, predicate, common.Constants.CL);
            List<KeySlice> liststatus = new ArrayList<KeySlice>();
            for (int i = 0; i < mapstatus.size(); i++)
            {
                liststatus.add(new KeySlice(listStatusID.get(i), mapstatus.get(listStatusID.get(i))));
            }
            result = ParseToJSON(liststatus);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    //Lấy danh sách 20 câu status nổi bật nhất
    public String listOutstandingStatus()
    {
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content)); 
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_likecount));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_dislikecount));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = 20;
            List<KeySlice> liststatus = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            liststatus = Sort(liststatus);
            
            result = ParseToJSON(liststatus);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    private List<KeySlice> Sort(List<KeySlice> list) throws UnsupportedEncodingException
    {
        for (int i=0; i<list.size()-1; i++)
            for (int j=i+1; j<list.size(); j++)
            {
                if (OutstandingPoint(list.get(i)) < OutstandingPoint(list.get(j)))
                {
                    KeySlice temp = list.get(i);
                    list.set(i, list.get(j));
                    list.set(j, temp);
                }
            }
        List<KeySlice> result = list.subList(0, 19);
        return result;
    }
    
    //Tính điểm nổi bật của từng status like * 8 + dislike * 2
    private int OutstandingPoint(KeySlice x) throws UnsupportedEncodingException
    {
        int like = 0,dislike = 0;
        for (ColumnOrSuperColumn columnOrSuperColumn : x.getColumns()) {
            if(columnOrSuperColumn.column.name == common.GeneralHandling.toByteBuffer(Status.colname_likecount))
                like = Integer.parseInt(common.GeneralHandling.toString(columnOrSuperColumn.column.value));
            if(columnOrSuperColumn.column.name == common.GeneralHandling.toByteBuffer(Status.colname_dislikecount))
                dislike = Integer.parseInt(common.GeneralHandling.toString(columnOrSuperColumn.column.value));
        }
        return like * 8 + dislike * 2;
    }
    
    //Tăng số like lên 1
    public boolean increaseLikecount(String status_ID)
    {
        boolean result = Inscrease(status_ID,Status.colname_likecount);
        return result;
}
    
    //Tăng số dislike lên 1
    public boolean increaseDislikecount(String status_ID)
    {
        boolean result = Inscrease(status_ID,Status.colname_dislikecount);
        return result;
    }
    
    private boolean Inscrease(String status_ID,String typecol)
    {
        boolean result = false;
        try {
            ByteBuffer id = common.GeneralHandling.toByteBuffer(status_ID);
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            ColumnPath path = new ColumnPath(Status.col_parent);
            path.column = common.GeneralHandling.toByteBuffer(typecol);
            ColumnOrSuperColumn status = client.get(id, path, common.Constants.CL);
            
            int likecount_curr = Integer.parseInt(common.GeneralHandling.toString(status.column.value));
            Column newcol = common.GeneralHandling.createCol(typecol, Integer.toString(likecount_curr + 1));
            
            client.insert(id, parent, newcol, common.Constants.CL);
            result = true;
        } catch (NotFoundException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public void UpdatelistTag(List<ByteBuffer> liststatusID,String nameTag)
    {
        
        for (ByteBuffer rowkey : liststatusID) {
            try {
                SlicePredicate predicate = new SlicePredicate();
                predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
                ColumnParent parent = new ColumnParent(Status.col_parent);
                
                List<ColumnOrSuperColumn> result = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
                String tags = common.GeneralHandling.toString(result.get(0).column.value);
                tags = tags.replaceAll("," + nameTag, "");
                tags = tags.replaceAll(nameTag + ",", "");
                client.insert(rowkey, parent, common.GeneralHandling.createCol(Status.colname_tags, tags), common.Constants.CL);
            
            } catch (InvalidRequestException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UnavailableException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TimedOutException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        }
        
    }

    public String listStatus(Page starKey){
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_createdate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_modifydate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_state));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer(starKey.getStar_key());
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.setCount(starKey.getLimit());
            List<KeySlice> p_listkey = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            KeySlice lastKeySlide = p_listkey.get(p_listkey.size() -1);
            result = ParseToJSON(p_listkey);
            starKey.setStar_key(lastKeySlide.getKey().toString());
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result; 
    }    

    public String listStatus(String starKey, String limit){
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_createdate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_modifydate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_state));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer(starKey);
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = Integer.parseInt(limit);
            List<KeySlice> p_listkey = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            result = ParseToJSON(p_listkey);
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result; 
    }
    
    public String listPhanTrang_Test(int limit){
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_content));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_createdate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_modifydate));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_state));
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_tags));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = 12;
            
            List<KeySlice> p_listkey = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            KeySlice lastKeySlide = p_listkey.get(p_listkey.size() -1);
            result = ParseToJSONPhanTrang(p_listkey, limit);
            System.out.println(ParseToJSONKeySlice(p_listkey));
            System.out.println(result);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result; 
    }       
    
    public String listPaging(String limit){
        String result = "";
        try {
            ColumnParent parent = new ColumnParent(Status.col_parent);
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_createdate));
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = Short.MAX_VALUE;
            
            List<KeySlice> p_listkey = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            result = ParseToJSONPhanTrang(p_listkey, Integer.parseInt(limit));
        } catch (InvalidRequestException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result; 
    }
    
    public String searchStatusByTag(String value, String start, String end, String filter) throws Exception
    {
        String result = "";
        int _start = Integer.parseInt(start);
        int _end = Integer.parseInt(end);
        int _filter = Integer.parseInt(filter);
        ArrayList<String[]> list = (new solrSearch()).searchStatusByTag(value, _start, _end, _filter);
        
        result = ParseToJSON(GetlistkeysliceFromArray(list));
        return result;
    }
    
    public String searchStatusByContent(String value, String start, String end, String filter) throws Exception
    {
        String result = "";
        int _start = Integer.parseInt(start);
        int _end = Integer.parseInt(end);
        int _filter = Integer.parseInt(filter);
        ArrayList<String[]> list = (new solrSearch()).searchStatusByContent(value, _start, _end, _filter);
        
        result = ParseToJSON(GetlistkeysliceFromArray(list));
        return result;
    }
    
    private List<KeySlice> GetlistkeysliceFromArray(ArrayList<String[]> list)
    {
        List<KeySlice> listkey = new ArrayList<KeySlice>();
        for (String[] temp : list) {
            try {
                KeySlice keyslice = new KeySlice();
                keyslice.key = common.GeneralHandling.toByteBuffer(temp[0]);
                
                ColumnOrSuperColumn colsuper = new ColumnOrSuperColumn();
                colsuper.column = common.GeneralHandling.createCol(Status.colname_content, temp[1]);
                keyslice.addToColumns(colsuper);
                
                ColumnOrSuperColumn colsuper1 = new ColumnOrSuperColumn();
                colsuper1.column = common.GeneralHandling.createCol(Status.colname_createdate, temp[2]);
                keyslice.addToColumns(colsuper1);
                
                ColumnOrSuperColumn colsuper2 = new ColumnOrSuperColumn();
                colsuper2.column = common.GeneralHandling.createCol(Status.colname_modifydate, temp[3]);
                keyslice.addToColumns(colsuper2);
                
                ColumnOrSuperColumn colsuper3 = new ColumnOrSuperColumn();
                colsuper3.column = common.GeneralHandling.createCol(Status.colname_state, temp[4]);
                keyslice.addToColumns(colsuper3);
                
                ColumnOrSuperColumn colsuper4 = new ColumnOrSuperColumn();
                colsuper4.column = common.GeneralHandling.createCol(Status.colname_tags, temp[5]);
                keyslice.addToColumns(colsuper4);
                listkey.add(keyslice);
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return listkey;
    }
    
    public String ParseToJSONKeySlice(List<KeySlice> list)
    {
        String result = "{\"result\":[";
        for(int i = 0; i < list.size(); i++){
            result += "{\"slice_key\":\"" + list.get(i).getKey().toString() + "\"";
            result += "},";            
        }
        int viTriCuoi = result.length();
        result = result.substring(0, viTriCuoi - 1);
        result += "]}";
        return result;
    }    

    public String ParseToJSONPhanTrang(List<KeySlice> list, int limit)
    {
        String result = "{\"result\":[";
        for(int i = 0; i < list.size();){
            result += "{\"start_key\":\"" + list.get(i).getKey().toString() + "\"},";
            i += limit;        
        }
        int viTriCuoi = result.length();
        result = result.substring(0, viTriCuoi - 1);
        result += "]}";
        return result;
    }      
    
    public String ParseToJSON(List<KeySlice> list)
    {
        String result = "{\"result\":[";
        for (KeySlice keySlice : list) {
            
            if (keySlice.columns.size() < 2)
                continue;
            try {
                result += "{\"status_ID\":\"" + common.GeneralHandling.toString(keySlice.key) + "\"";
                boolean tags = false;
                for (ColumnOrSuperColumn col : keySlice.columns) {
                    Column c = col.column;
                    
                    String colname = common.GeneralHandling.toString(c.name);
                    if (colname.equals(Status.colname_content))
                    {
                        String content = common.GeneralHandling.toString(c.value);
                        content = content.replace("\"","“");
                        content = StringEscapeUtils.escapeJava(content);
                        
                        result += ",\"" + Status.colname_content + "\":\"" + (content) + "\"";
                        
                    }
                    else if(colname.equals(Status.colname_tags))
                    {
                        tags = true;
                        String[] listtag = common.GeneralHandling.toString(c.value).split(",");
                        result += ",\"" + Status.colname_tags + "\":[";
                        for (int i = 0; i < listtag.length; i++){
                            result +=  "\"" + listtag[i] + "\",";
                        }
                        result = result.substring(0, result.length() - 1);
                        result += "],";
                    }
                    else if (colname.equals(Status.colname_createdate))
                    {
                        String createdate = common.GeneralHandling.toString(c.value);
                        result += ",\"" + Status.colname_createdate + "\":\"" + createdate + "\"";
                        
                    }
                    else if (colname.equals(Status.colname_modifydate))
                    {
                        String modifydate = common.GeneralHandling.toString(c.value);
                        result += ",\"" + Status.colname_modifydate + "\":\"" + modifydate + "\"";
                        
                    }
                    else if (colname.equals(Status.colname_state))
                    {
                        String state = common.GeneralHandling.toString(c.value);
                        result += ",\"" + Status.colname_state + "\":\"" + state + "\"";
                        
                    }
                    else if (colname.equals(Status.colname_likecount))
                    {
                        String like = common.GeneralHandling.toString(c.value);
                        result += ",\"" + Status.colname_likecount + "\":\"" + like + "\"";
                        
                    }
                    else if (colname.equals(Status.colname_dislikecount))
                    {
                        String dislike = common.GeneralHandling.toString(c.value);
                        result += ",\"" + Status.colname_dislikecount + "\":\"" + dislike + "\"";
                        
                    }
                        
                }
                if (!tags)
                    result += ",\"" + Status.colname_tags + "\":[]},";
                result = result.substring(0, result.length()-1);
                result += "},";
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(StatusDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        int x = result.length();
        result = result.substring(0, x - 1);
        result += "]}";
        return result;
    }
}
